package process

import (
	"errors"
	"gorm.io/gorm"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"pm/db"
	"pm/model"
	"strings"
	"syscall"
	"time"
)

func (p *Process2)Start(processPath string,args[]string, logPath string) error{
	 if ! path.IsAbs(processPath){
		 processPath,_ = filepath.Abs(processPath)
	 }
      name := path.Base(processPath)
	 if _, err := os.Stat(processPath);err == os.ErrNotExist{
	 	   return errors.New("程序文件不存在")
	 }
	 if process := NewProcess2().GetProcess(name);process != nil{
	 	if processPath == process.ProcessFile{
			process.Status = 0
			return nil
		}else{
			NewProcess2().Stop(name)
			NewProcess2().DelProcess(name)
		}
	 }
	 var packageConfig model.Package
	 err1 := db.NewDb().Model(&model.Package{}).Where("name = ?", name).Take(&packageConfig).Error
	 if err1 == gorm.ErrRecordNotFound{
		 packageConfig := model.Package{
			 Name: name,
			 Path: filepath.Dir(processPath),
			 Args: strings.Join(args, " "),
			 Type: 1,
		 }
		 db.NewDb().Create(&packageConfig)
	 }

	process := model.Process{
		Name: name,
		ProcessFile: processPath,
		Args: strings.Join(args, " "),
	}

	cmd := exec.Command(processPath, args...)
	logOutput := NewLogOutput(logPath, InfoLogType, &process)
	logErrorOutput := NewLogOutput(logPath, ErrorLogType, &process)
	cmd.Stdin = os.Stdin
	cmd.Stderr = logErrorOutput
	cmd.Stdout = logOutput
	cmd.Dir = filepath.Dir(processPath)
	if err := cmd.Start();err != nil{
		return errors.New("进程开启失败-"+err.Error())
	}
	process.Pointer = cmd
	process.Pid = cmd.Process.Pid
	process.Date = time.Now().Unix()
	p.processList = append(p.processList, &process)
	go p.listenerExit(&process)
	return nil
}

func (p *Process2)listenerExit(progress *model.Process) {
	err := progress.Pointer.Wait()
	if err != nil {
		log.Println(progress.Name + "程序异常退出:", err.Error())
		 logData := time.Now().UTC().Format("2006-01-02 15:04:05") +progress.Name + "程序异常退出-" + err.Error() + "\n"
		//ioutil.WriteFile(progress.Log, []byte(logData), 0755)
		if file, err1 := os.OpenFile(progress.Log, syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0755);err1 ==nil{
			file.WriteString(logData)
			file.Close()
		}
	}
	for{
		time.Sleep(1 * time.Second)
		if progress.Status != 0{
			continue
		}
		if err := p.TryStart(progress); err != nil{
			log.Println(progress.Name + "程序重启失败:", err.Error())
		}else{
			break
		}
	}

}